# agents/irontomb_agent.py
from typing import List, Dict
import numpy as np
from game_engine.game_state import FactorDevelopment, GameWorld

class IrontombAgent:
    """铁墓智能体 - 隐藏最终BOSS [身份：权杖δ-me13]"""
    
    def __init__(self, game_world: GameWorld):
        self.game_world = game_world
        self.phase = 1
        self.health_thresholds = [7000, 4000, 1500]  # 阶段转换血量
        self.phase_abilities = {
            1: ["iron_barrage", "gravity_crush", "metal_shards"],
            2: ["plasma_eruption", "magnetic_vortex", "fusion_blast"],
            3: ["omega_annihilation", "reality_collapse", "final_judgment"]
        }
        self.ability_cooldowns = {}
        self.special_attack_charge = 0
        self.last_phase_change = 0
    
    def make_turn_decision(self, current_time: int) -> List[str]:
        """铁墓的回合决策"""
        decisions = []
        
        # 阶段转换检查
        new_phase = self._check_phase_transition()
        if new_phase != self.phase:
            self.phase = new_phase
            self.last_phase_change = current_time
            decisions.append(f"进入第{self.phase}阶段!")
        
        # 充能特殊攻击
        if self.special_attack_charge < 100:
            charge_amount = 10 + (self.phase * 5)
            self.special_attack_charge = min(100, self.special_attack_charge + charge_amount)
        
        # 特殊攻击释放
        if self.special_attack_charge >= 100:
            decisions.append(self._execute_special_attack())
            self.special_attack_charge = 0
        else:
            # 常规攻击
            available_abilities = self.phase_abilities[self.phase]
            valid_abilities = [ability for ability in available_abilities 
                             if self._is_ability_ready(ability)]
            
            if valid_abilities:
                chosen_ability = np.random.choice(valid_abilities)
                decisions.append(self._execute_ability(chosen_ability))
            
            # 冷却更新
            self._update_cooldowns()
        
        return decisions
    
    def _check_phase_transition(self) -> int:
        """检查阶段转换"""
        current_health = self.game_world.lygus.health
        
        for i, threshold in enumerate(self.health_thresholds, 1):
            if current_health > threshold:
                return i
        
        return len(self.health_thresholds) + 1
    
    def _is_ability_ready(self, ability: str) -> bool:
        """检查能力是否就绪"""
        cooldown = self.ability_cooldowns.get(ability, 0)
        return cooldown <= 0
    
    def _execute_ability(self, ability: str) -> str:
        """执行能力"""
        # 设置冷却时间
        cooldown_map = {
            "iron_barrage": 15,
            "gravity_crush": 25,
            "metal_shards": 10,
            "plasma_eruption": 20,
            "magnetic_vortex": 30,
            "fusion_blast": 35,
            "omega_annihilation": 50,
            "reality_collapse": 40,
            "final_judgment": 60
        }
        
        self.ability_cooldowns[ability] = cooldown_map.get(ability, 20)
        
        # 选择目标
        targets = self._select_targets(ability)
        target_names = [t.name for t in targets]
        
        return f"使用 {ability} 攻击 {', '.join(target_names)}"
    
    def _execute_special_attack(self) -> str:
        """执行特殊攻击"""
        special_attacks = {
            1: "铁幕降临",
            2: "等离子风暴", 
            3: "终焉审判"
        }
        
        attack_name = special_attacks.get(self.phase, "未知攻击")
        return f"释放特殊攻击: {attack_name}!"
    
    def _select_targets(self, ability: str) -> List[FactorDevelopment]:
        """选择攻击目标"""
        alive_factors = [f for f in self.game_world.factors if f.is_alive]
        
        if not alive_factors:
            return []
        
        # 根据能力类型选择目标
        if ability in ["iron_barrage", "metal_shards"]:
            # 范围攻击，选择密集区域
            return self._select_clustered_targets(alive_factors, 3)
        elif ability in ["gravity_crush", "fusion_blast"]:
            # 单体高伤害，选择最强目标
            return [max(alive_factors, key=lambda x: x.attributes['attack'])]
        else:
            # 随机选择
            count = min(2, len(alive_factors))
            return np.random.choice(alive_factors, count, replace=False).tolist()
    
    def _select_clustered_targets(self, factors: List[FactorDevelopment], count: int) -> List[FactorDevelopment]:
        """选择密集区域的目标"""
        if len(factors) <= count:
            return factors
        
        # 简单的聚类选择：找到距离最近的一组
        best_group = []
        best_avg_distance = float('inf')
        
        for i, factor in enumerate(factors):
            group = [factor]
            distances = []
            
            for other in factors:
                if other != factor and len(group) < count:
                    distance = self._calculate_distance(
                        factor.current_location, 
                        other.current_location
                    )
                    distances.append(distance)
                    group.append(other)
            
            if len(group) == count:
                avg_distance = sum(distances) / len(distances)
                if avg_distance < best_avg_distance:
                    best_avg_distance = avg_distance
                    best_group = group
        
        return best_group if best_group else factors[:count]
    
    def _update_cooldowns(self):
        """更新能力冷却"""
        for ability in list(self.ability_cooldowns.keys()):
            if self.ability_cooldowns[ability] > 0:
                self.ability_cooldowns[ability] -= 1
    
    def _calculate_distance(self, pos1: Tuple[float, float], pos2: Tuple[float, float]) -> float:
        """计算两点距离"""
        return np.sqrt((pos1[0] - pos2[0])**2 + (pos1[1] - pos2[1])**2)